namespace OasisCiq.Xnl
{
    // TODO: XLink attributes

    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using CommonTypes;
    using External;
    using Xml;
    using XS;

    /// <summary>
    /// Reusable complex type for a party. A party is a person or an organisation
    /// </summary>
    public class PartyNameType : 
        IDataQualityGroup,
        IValidityDateGroup,
        ILanguageCodeGroup,
        IXLink,
        IExtendedAttributes,
        IXmlSerializable
    {
        private static readonly XmlQualifiedName XmlElementName =
            new XmlQualifiedName("PartyName", XmlNamespaces.Name);

        public virtual ICollection<NameLine> NameLines { get; set; }

        public virtual ICollection<PersonNameType> PersonNames { get; set; }

        public virtual ICollection<OrganisationNameType> OrganisationNames { get; set; }

        /// <summary>
        /// A unique identifier of a party
        /// </summary>
        public virtual CTString PartyNameId { get; set; }

        /// <summary>
        /// Type of Party Name ID
        /// </summary>
        public virtual PartyNameIdTypeList PartyNameIdType { get; set; }

        /// <summary>
        /// Globally unique identifier
        /// </summary>
        public virtual CTString Id { get; set; }

        /// <summary>
        /// Type of use of this data. e.g. data exchange, contact, update, create
        /// </summary>
        public virtual PartyNameUsageList Usage { get; set; }

        /// <summary>
        /// Status of the entity. e.g. Old, Current, Inactive, Active, etc
        /// </summary>
        public virtual StatusList Status { get; set; }

        /// <summary>
        /// The connector used to join more than one person name.
        /// <example>
        /// Mr Hunt AND Mrs Clark, where AND is the JointNameConnector.
        /// The flow is from the preceding to the following.
        /// If there is more than 2 names then all names are connected using
        /// this connector in the natural order.
        /// </example>
        /// </summary>
        public virtual JointNameConnectorList JointNameConnector { get; set; }

        public virtual XSDateTime DateValidFrom { get; set; }

        public virtual XSDateTime DateValidTo { get; set; }

        public virtual NameKeyGroup NameKey { get; set; }

        public virtual DataQualityTypeList DataQualityType { get; set; }

        public virtual XSDateTime ValidFrom { get; set; }

        public virtual XSDateTime ValidTo { get; set; }

        public virtual XSLanguage LanguageCode { get; set; }

        public virtual NameValueCollection ExtendedAttributes { get; set; }

        #region IXmlSerializable implementation

        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }

        public virtual void ReadXml(XmlReader reader)
        {
            var wrapper = XmlUtilities.Wrap(reader);
            if (XmlUtilities.MoveToElement(wrapper, XmlElementName))
            {
                new XnlXmlReader(wrapper).ReadPartyName(
                    this,
                    XmlElementName.Name,
                    XmlElementName.Namespace);
            }
        }

        public virtual void WriteXml(XmlWriter writer)
        {
            new XnlXmlWriter(writer).WritePartyName(this);
        }

        #endregion
    }
}